Cpufreq: Enhance hypervisor px sanity check
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 3 Nov 2008 10:24:17 +0000 (10:24 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 3 Nov 2008 10:24:17 +0000 (10:24 +0000)
This patch enhances hypervisor px sanity check in 2 level:
Firstly, move per-cpu-level px sanity check from each cpufreq driver
to common point (@ hypercall path). Secondly, add per-domain-level px
sanity check to common point (@ cpufreq_add_cpu).

Signed-off-by: Jinsong Liu <jinsong.liu@intel.com>
xen/arch/ia64/xen/cpufreq/cpufreq.c
xen/arch/x86/acpi/cpufreq/cpufreq.c
xen/drivers/cpufreq/cpufreq.c

index b26f8550cf2f0e6ee705e162c7c4ee85799f555d..47f5bc4a1f1bf796f826983b165ce37bb888fa17 100644 (file)
@@ -209,21 +209,6 @@ acpi_cpufreq_cpu_init (struct cpufreq_policy *policy)
 
        data->acpi_data = &processor_pminfo[cpu]->perf;
 
-       /* capability check */
-       if (data->acpi_data->state_count <= 1) {
-               printk(KERN_WARNING "P-States\n");
-               result = -ENODEV;
-               goto err_unreg;
-       }
-
-       if ((data->acpi_data->control_register.space_id !=
-                               ACPI_ADR_SPACE_FIXED_HARDWARE) ||
-                       (data->acpi_data->status_register.space_id !=
-                        ACPI_ADR_SPACE_FIXED_HARDWARE)) {
-               result = -ENODEV;
-               goto err_unreg;
-       }
-
        data->freq_table = xmalloc_array(struct cpufreq_frequency_table,
                        (data->acpi_data->state_count + 1));
        if (!data->freq_table) {
index 3b34269d6477102f8c36f80347c286a7735715b1..94b66d3581d39eae295e4a073a9cd570f152724f 100644 (file)
@@ -447,18 +447,6 @@ acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
     perf = data->acpi_data;
     policy->shared_type = perf->shared_type;
 
-    /* capability check */
-    if (perf->state_count <= 1) {
-        printk("No P-States\n");
-        result = -ENODEV;
-        goto err_unreg;
-    }
-
-    if (perf->control_register.space_id != perf->status_register.space_id) {
-        result = -ENODEV;
-        goto err_unreg;
-    }
-
     switch (perf->control_register.space_id) {
     case ACPI_ADR_SPACE_SYSTEM_IO:
         printk("xen_pminfo: @acpi_cpufreq_cpu_init,"
index 26101b80862035df88d3354ce682a2e8f82fdfae..8777a8a822e9c4893ecae4e90f6b7dc43125c8d3 100644 (file)
@@ -117,6 +117,15 @@ int cpufreq_add_cpu(unsigned int cpu)
         cpu_set(cpu, cpufreq_dom->map);
         cpu_set(cpu, policy->cpus);
 
+        /* domain coordination sanity check */
+        if ((perf->domain_info.coord_type !=
+             processor_pminfo[firstcpu]->perf.domain_info.coord_type) ||
+            (perf->domain_info.num_processors !=
+             processor_pminfo[firstcpu]->perf.domain_info.num_processors)) {
+            ret = -EINVAL;
+            goto err2;
+        }
+
         printk(KERN_EMERG"adding CPU %u\n", cpu);
     } else {
         cpufreq_dom = xmalloc(struct cpufreq_dom);
@@ -303,6 +312,24 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
 
     if ( dom0_px_info->flags & XEN_PX_PCT )
     {
+        /* space_id check */
+        if (dom0_px_info->control_register.space_id != 
+            dom0_px_info->status_register.space_id)
+        {
+            ret = -EINVAL;
+            goto out;
+        }
+
+#ifdef CONFIG_IA64
+        /* for IA64, currently it only supports FFH */
+        if (dom0_px_info->control_register.space_id !=
+            ACPI_ADR_SPACE_FIXED_HARDWARE)
+        {
+            ret = -EINVAL;
+            goto out;
+        }
+#endif
+
         memcpy ((void *)&pxpt->control_register,
                 (void *)&dom0_px_info->control_register,
                 sizeof(struct xen_pct_register));
@@ -312,8 +339,16 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
         print_PCT(&pxpt->control_register);
         print_PCT(&pxpt->status_register);
     }
+
     if ( dom0_px_info->flags & XEN_PX_PSS ) 
     {
+        /* capability check */
+        if (dom0_px_info->state_count <= 1)
+        {
+            ret = -EINVAL;
+            goto out;
+        }
+
         if ( !(pxpt->states = xmalloc_array(struct xen_processor_px,
                         dom0_px_info->state_count)) )
         {
@@ -325,14 +360,28 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
         pxpt->state_count = dom0_px_info->state_count;
         print_PSS(pxpt->states,pxpt->state_count);
     }
+
     if ( dom0_px_info->flags & XEN_PX_PSD )
     {
+#ifdef CONFIG_X86
+        /* for X86, check domain coordination */
+        /* for IA64, _PSD is optional for current IA64 cpufreq algorithm */
+        if (dom0_px_info->shared_type != CPUFREQ_SHARED_TYPE_ALL &&
+            dom0_px_info->shared_type != CPUFREQ_SHARED_TYPE_ANY &&
+            dom0_px_info->shared_type != CPUFREQ_SHARED_TYPE_HW)
+        {
+            ret = -EINVAL;
+            goto out;
+        }
+#endif
+
         pxpt->shared_type = dom0_px_info->shared_type;
         memcpy ((void *)&pxpt->domain_info,
                 (void *)&dom0_px_info->domain_info,
                 sizeof(struct xen_psd_package));
         print_PSD(&pxpt->domain_info);
     }
+
     if ( dom0_px_info->flags & XEN_PX_PPC )
     {
         pxpt->platform_limit = dom0_px_info->platform_limit;
@@ -340,7 +389,6 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
 
         if ( pxpt->init == XEN_PX_INIT )
         {
-
             ret = cpufreq_limit_change(cpuid); 
             goto out;
         }